package com.game.basic;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;

import com.defence.R;
import com.game.utils.ImageTool;
import com.opengltest.ColorSquare;
import com.opengltest.Group;
import com.opengltest.Mesh;
import com.opengltest.SimpleCube;
import com.opengltest.SimplePlane;
import com.opengltest.Sixcorn;
import com.opengltest.SixcornTexture;
import com.opengltest.Square;


/**
* @author oven:
* @version 创建时间：2013-1-25 上午11:48:58
* 
* 渲染器, 执行绘制
* 
* 
* 方法详解:
* 
* 【glClear】清理缓冲区，并设置为预设值。 public void glClear(int mask)
*   glClear设置窗口位面区的值，该值由glClearColor, glClearDepth 和 glClearStencil等方法选择出。
	像素所有权测试、裁剪测试、抖动、颜色缓冲区掩饰将影响glClear操作，裁剪盒绑定清理区域。Alpha功能、混合功能、逻辑操作、建模、纹理映射以及深度缓冲区会被glClear操作忽略。
	glClear可以使参数为多个值按位与后的结果，以表明那个缓冲区需要清理。
	有如下值：
	GL_COLOR_BUFFER_BIT：表明颜色缓冲区。
	GL_DEPTH_BUFFER_BIT：表明深度缓冲区。
	GL_STENCIL_BUFFER_BIT：表明模型缓冲区。
	
	glClear（）语句的作用是用当前缓冲区清除值，也就是glClearColor或者glClearDepth等函数所指定的值来清除指定的缓冲区。比如：
	glClearColor（0.0，0.0，0.0，0.0）;
	glClear（GL_COLOR_BUFFER_BIT）;
	第一条语句表示清除颜色设为黑色，第二条语句表示把整个窗口清除为当　前的清除颜色，glClear（）的唯一参数表示需要被清除的缓冲区。
	
      【glClear】指定颜色缓冲区的清理值 public void glClearColor(float red,float green,float blue,float alpha)
      glClearColor指明红、绿、蓝、alpha的值并通过glClear来清理颜色缓冲区，被glClearColor指明的值属于区间[0, 1]。
      red——指明颜色缓冲区被清理时红色的值，初始值为0。
	  green——指明颜色缓冲区被清理时绿色的值，初始值为0。
	  blue——指明颜色缓冲区被清理时蓝色的值，初始值为0。
	  alpha——指明颜色缓冲区被清理时alpha的值，初始值为0。
	  
     【glClearDepthf】指明深度缓冲区的清理值 public void glClearDepthf(float depth)
     glClearDepth方法指明深度值，并通过glClear来清理深度缓冲区。glClearDepth指明的值属于区间[0, 1]。
     depth——指明深度缓冲区被清理时的深度值，初始值为1。
     
     【glClearStencil】指明模板缓冲区的清理值。public void glClearStencil(int s)
     glClearStencil指明glClear清理模板缓冲区时的索引，s为2m-1，其中m是模板缓冲区中的bit数。
     
     s——指明glClear清理模板缓冲区时的索引，初始值为0。
     
     【glClientActiveTexture】选择客户端活动纹理单元。 public void glClientActiveTexture(int texture)
     glClientActiveTexture选择顶点矩阵，客户状态参数由glTexCoordPointer方法修 改。可用性由glEnableClientState与glDisableClientState决定，参数为 GL_TEXTURE_COORD_ARRAY。
     
     texture——指定哪一个纹理单元为活动。纹理个数至少一个（对于1.0）或两个（对于1.1）纹理必须是一个GL_TEXTUREi，其中0 <=i < GL_MAX_TEXTURE_UNITS，初始值为GL_TEXTURE0。
   
     【glColor4f】设置当前颜色。 public void glColor4f(float red,float green,float blue,float alpha)
     GL储存当前四值的RGBA颜色，glColor可以设置新的四值的RGBA颜色。
 	  当前颜色值被储存为整型或浮点型，如果值被储存为浮点型，尾数和指数的大小未指明。
	在当前颜色更新之前整型与浮点型都不属于区间[0, 1]，然而颜色元素在修改或写入颜色缓冲区前会属于该区间。
	
	red——为当前颜色指明一个新的红色值，初始值为1。
	green——为当前颜色指明一个新的绿色值，初始值为1。
	blue——为当前颜色指明一个新的蓝色值，初始值为1。
	alpha——为当前颜色指明一个新的alpha值，初始值为1。
	
     【glColorMask】开启与禁止颜色元素的写入操作。 public void glColorMask(boolean red,boolean green,boolean blue,boolean alpha)
     glColorMask指明单独的颜色元素是否可以被写入。举一个例子，如果red为false，则颜色缓冲区中的任何像素的颜色的红色元素将不会发生变化，忽略企图的绘画操作，包括glClear。
	  不可以控制元素单个位的改变，只能控制整个元素是否可以改变。
	  
	 red——指明红色元素是否可以写入颜色缓冲区，初始值为ture，表明可以写入。
	 green——指明绿色元素是否可以写入颜色缓冲区，初始值为ture，表明可以写入。
	 blue——指明蓝色元素是否可以写入颜色缓冲区，初始值为ture，表明可以写入。
	 alpha——指明alpha元素是否可以写入颜色缓冲区，初始值为ture，表明可以写入。
	 
      【glColorPointer】定义一个颜色矩阵。public void glColorPointer(int size,int type,int stride,Buffer pointer)
      glColorPointer指明渲染时使用的颜色矩阵。size指明每个颜色的元素数量，必须为4。type指明每个 颜色元素的数据类型，stride指明从一个颜色到下一个允许的顶点的字节增幅，并且属性值被挤入简单矩阵或存储在单独的矩阵中（简单矩阵存储可能在一些 版本中更有效率）。
	当一个颜色矩阵被指定，size, type, stride和pointer将被保存在客户端状态。
	如果颜色矩阵被启用，当使用glDrawArrays方法或glDrawElements方法时被调用。利用 glEnableClientState方法与glDisableClientState方法以GL_COLOR_ARRAY为参数来启用和禁止颜色矩 阵，颜色矩阵初始值为禁用，不允许glDrawArrays方法和glDrawElements方法调用。
	使用glDrawArrays方法依据事先指明的顶点和顶点矩阵构建一系列图元（都是同种类型的），使用glDrawElements方法依据顶点索引和顶点属性构建一系列图元。
	
	size——指明每个颜色的元素数量，必须为4。
	type——指明每个矩阵中颜色元素的数据类型，允许的符号常量有GL_UNSIGNED_BYTE, GL_FIXED和GL_FLOAT，初始值为GL_FLOAT。
	stride——指明连续的点之间的位偏移，如果stride为0时，颜色被紧密挤入矩阵，初始值为0。
	pointer——指明包含颜色的缓冲区，如果pointer为null，则为设置缓冲区。
	
     【glFrontFace】定义多边形的正面和背面。 public void glFrontFace(int mode)
	在一个完全由不透明的密闭surface组成的场景中，多边形的背面永远不会被看到。剔除这些不能显示出来的面可以加速渲染器渲染图像的时间。开启和禁用剔除功能，调用glEnable和glDisable方法并以GL_CULL_FACE为参数。剔除功能初始值为禁止。
	如果一个虚拟的对象从第一个顶点，到第二个顶点，等等，直到最后一个顶点，这个多边形顶点移动的方向是按顺时针移动的，则这个多边形窗口坐标上的投 影被认为是按顺时针绘出的。
	glFrontFace指明多边形在窗口坐标中是顺时的还是逆时针被作为正面。传递GL_CCW给 mode则选择逆时针多边形为正面，GL_CW则选择顺时针多边形为正面。默认逆时针多边形为正面。
	
	mode——多边形正面的方向。GL_CW和GL_CCW被允许，初始值为GL_CCW。
	
     【glEnable】启用服务器端GL功能。 public void glEnable(int cap)
     glEnable方法和glDisable方法可以启用和禁止各种功能，各种功能（除了GL_DITHER和GL_MULTISAMPLE）的初始值为GL_FALSE。
	glEnable方法和glDisable方法都只有一个参数，它可以采用下列值中的一个：GL_ALPHA_TEST——如果启用，将进行alpha测试，详见glAlphaFunc。
	GL_BLEND——如果启用，将引入的值与颜色缓冲区中的值混合，详见glBlendFunc。
	GL_COLOR_LOGIC_OP——如果启用，允许（apply）引入的颜色与颜色缓冲区中的值进行逻辑运算。详见glLogicOp。
	GL_COLOR_MATERIAL——如果启用，得到当前颜色的周围散开的痕迹。
	GL_CULL_FACE——如果启用，基于窗口坐标采集多边形。详见glCullFace。
	GL_DEPTH_TEST——如果启用，做深度比较和更新深度缓存。值得注意的是即使深度缓冲区存在并且深度mask不是0，如果深度测试禁用的话，深度缓冲区也无法更新。详见glDepthFunc, glDepthMask和glDepthRange。
	GL_DITHER——如果启用颜色元素或索引将在被写入颜色缓冲区之前进行dither。
	GL_FOG——如果启用，将雾的颜色效果与显示纹理颜色混合。详见glFog。
	GL_LIGHTi——如果启用，包含光线i在光线方程的评价中，详见glLightModel和glLight。
	GL_LIGHTING——如果启用，用当前光线参数计算顶点颜色。否则仅仅简单将当前颜色与每个顶点关联。详见glMaterial, glLightModel和glLight。
	GL_LINE_SMOOTH——如果启用，画线时使用调整过滤。否则，画aliased线，详见glLineWidth。
	GL_MULTISAMPLE——如果启用，为单程反锯齿和其他效果显示多样本片段，详见glSampleCoverage
	GL_NORMALIZE——如果启用，法向量被计算为单位向量，详见glNormal和glNormalPointer。
	GL_POINT_SMOOTH——如果启用，使用调整过滤器描绘点，否则，画aliased点，详见glPointSize。
	GL_POLYGON_OFFSET_FILL——如果启用，在深度比较进行前多边形片段的深度值会进行移位。
	GL_RESCALE_NORMAL——如果启用，法向量的刻度由视图模型矩阵中的元素确定，详见glNormal和glNormalPointer。
	GL_SAMPLE_ALPHA_TO_MASK（仅1.0）——如果启用，将alpha值转变为多样本范围修正码。详见glSampleCoverage。
	GL_SAMPLE_ALPHA_TO_COVERAGE（仅1.1）——如果启用，将会产生一个范围值，它的每个bit都是由相应的样本位置的alpha值决定的。
	GL_SAMPLE_ALPHA_TO_ONE——如果启用，在计算完多样本范围修正码后将片段alpha值设为被允许的最大值。详见glSampleCoverage。
	GL_SAMPLE_MASK（仅1.0）——如果启用，在进行多样本时，申请一个码来修改片段范围。
	GL_SAMPLE_COVERAGE（仅1.1）——如果启用，片段范围会与另一个临时的范围值进行与运算。这个临时的范围值与上文中 GL_SAMPLE_ALPHA_TO_COVERAGE描述的范围值的确定方式相同。但是作为GL_SAMPLE_COVERAGE_VALUE的值的 功能，如果GL_SAMPLE_COVERAGE_VALUE为GL_TRUE，在它与片段范围值进行与运算前，这个临时的范围值是倒置的（所以bit的 值都是倒置的），详见glSampleCoverage。
	GL_SCISSOR_TEST——如果启用，丢弃裁剪矩形外的片段。详见glScissor。
	GL_STENCIL_TEST——如果启用，做模板测试并更新模板缓冲区，详见glStencilFunc，glStencilMask和glStencilOp。
	GL_TEXTURE_2D——如果启用，当前活动纹理单元为二维纹理。详见glActiveTexture,glTexImage2D,glCompressedTexImage2D和glCopyTexImage2D
	GL_CLIP_PLANEi——如果启用，裁剪面i可用。详见glClipPlane。
	GL_POINT_SPRITE_OES（1.1 + OES_point_sprite 扩展）——如果启用，点块纹理可用，详见glPointSize和glTexEnv。
	
      【glEnableClientState】启用客户端的某项功能。 public void glEnableClientState(int array)
      glEnableClientState和glDisableClientState启用或禁用客户端的单个功能。默认的，所有客户端功能禁用。
	array可以是下列符号常量：
	GL_COLOR_ARRAY——如果启用，颜色矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glColorPointer。
	GL_NORMAL_ARRAY——如果启用，法线矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glNormalPointer。
	GL_TEXTURE_COORD_ARRAY——如果启用，纹理坐标矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glTexCoordPointer。
	GL_VERTEX_ARRAY——如果启用，顶点矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glVertexPointer。
	GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)——如果启用，点大小矩阵控制大 小以渲染点和点sprites。这时由glPointSize定义的点大小将被忽略，由点大小矩阵提供的大小将被用来渲染点和点sprites。详见 glPointSize。
	
	array——指明启用的功能，允许的符号常量有 GL_COLOR_ARRAY,GL_NORMAL_ARRAY,GL_TEXTURE_COORD_ARRAY,GL_VERTEX_ARRAY，和 GL_POINT_SIZE_ARRAY_OES (OES_point_size_array extension)
	
     【glVertexPointer】定义一个顶点坐标矩阵。public void glVertexPointer(int size,int type,int stride,Buffer pointer)
     glVertexPointer指明当渲染时一个顶点坐标矩阵的存储单元和数据。
	当一个顶点矩阵被指明时，size, type, stride和pointer保存为客户端状态。
	如果顶点矩阵功能启用，当调用glDrawArrays方法或glDrawElements方法时会使用。想要启用或禁 止顶点矩阵，使用glEnableClientState或glDisableClientState方法，并以GL_VERTEX_ARRAY为参数。 顶点矩阵初始为禁止，调用glDrawArrays方法或glDrawElements方法时无效。
	调用glDrawArrays方法根据事先指明的点和顶点属性矩阵创建一系列图元（都有相同的类型）。调用glDrawElements方法根据顶点索引和顶点属性创建一系列图元。
	
	size——每个顶点的坐标维数，必须是2, 3或者4，初始值是4。
	type——指明每个顶点坐标的数据类型，允许的符号常量有GL_BYTE, GL_SHORT, GL_FIXED和GL_FLOAT，初始值为GL_FLOAT。
	stride——指明连续顶点间的位偏移，如果为0，顶点被认为是紧密压入矩阵，初始值为0。
	pointer——指明顶点坐标的缓冲区，如果为null，则没有设置缓冲区。
	
      【glDrawArrays】由矩阵数据渲染图元。 public void glDrawArrays(int mode,int first,int count)
      glDrawArrays通过很少的子程序调用指明多层几何图元。你可以设置独立的顶点、法线、颜色矩阵，以及纹理坐标，并仅需调用glDrawArrays就可以通过它们构建一系列图元。
	当glDrawArrays被调用，它从被允许访问的矩阵中计算连续count个元素来构建一系列几何图元，从first元素开始。mode指明哪一种图元将被构建及矩阵元素怎样构建这些图元。如果GL_VERTEX_ARRAY没有启用，则不会有图元产生。
	当glDrawArrays返回后，由glDrawArrays改变的顶点属性会得到一个未指明的值。举个例子，如果GL_COLOR_ARRAY被启用，则glDrawArrays执行后当前颜色的值是未定义的。未改变的属性仍然是已定义的。
	
	mode——指明渲染哪一种图元。允许的符号常量有GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN和GL_TRIANGLES。
	first——指明在允许访问的矩阵中的起始索引。
	count——指明要渲染的索引的数量。
	
     【glDrawElements】由矩阵数据渲染图元。  public void glDrawElements(int mode,int count,int type,Buffer indices)
     glDrawElements用少量调用指明多重几何图元，你可以事先指明独立的顶点、法线、颜色和纹理坐标矩阵并且可以通过调用glDrawElements方法来使用它们创建序列图元。
	当glDrawElements被调用，它会使用有序索引来查询可用矩阵中的元素，并以此创建序列几何图元，如果GL_VERTEX_ARRAY被禁用，则不会创建。
	顶点属性由glDrawElements修改，glDrawElements在返回后会有一个未指明的值。举一个例子，如果GL_COLOR_ARRAY启用，当执行glDrawElements方法后，当前颜色的值是未定义的，属性不会维持它之前的值。
	
	mode——指明被渲染的是哪种图元，被允许的符号常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP,GL_LINES,GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN和GL_TRIANGLES
	count——指明被渲染的元素个数。
	type——指明索引指的类型，不是GL_UNSIGNED_BYTE就是GL_UNSIGNED_SHORT。
	indices——指明存储索引的位置指针。
	
    【glTranslatef】用平移矩阵乘以当前矩阵。 public void glTranslatef(float x,float y,float z)
    glTranslate通过向量(x, y, z) 产生平移，以平移矩阵乘以当前矩阵（见glMatrixMode），用乘积代替当前矩阵，就好像调用glMultMatrix方法并以下列矩阵为参数：
	( 1       0       0      x )
	( 0       1       0      y )
	( 0       0       1      z )
	( 0       0       0      1 )
	如果矩阵模式是GL_MODELVIEW或GL_PROJECTION，则调用glTranslate方法后所绘的对象都将发生平移。
	使用glPushMatrix方法和glPopMatrix方法来保存没有平移的坐标系统。
	
	x——指明平移向量的x坐标。
	y——指明平移向量的y坐标。
	z——指明平移向量的z坐标。
	
	
    【glLoadIdentity】用特征矩阵代替当前矩阵。
    glLoadIdentity使特征矩阵代替当前矩阵。语义上等价于调用glLoadMatrix方法并以特征矩阵为参数。
	( 1       0       0       0 )
	( 0       1       0      0 )
	( 0       0       1      0 )
	( 0       0       0      1 )
	但在一些情况下它更高效。
	
     【glBindTexture】将一个已命名的纹理与一个纹理目标绑定。 public void glBindTexture(int target,int texture)
     glBindTexture可以让你创建或使用一个已命名的纹理，调用glBindTexture方法并将target设置为GL_TEXTURE_2D，将texture设置为你想要绑定的新纹理的名称。当一个纹理与目标绑定时，该目标之前的绑定关系将自动被释放。
	纹理的名称是一个无符号的整数。在每个纹理目标中，0被保留用以代表默认纹理。纹理名称与相应的纹理内容被保留在当前GL rendering上下文的共享的纹理对象空间中（参照eglCreateContext）
	你可以使用glGenTextures来设置一个新的纹理名称。
	当一个纹理被绑定时，对于其目标的GL操作将作用于该绑定的纹理之上。如果被绑定的纹理的目标的维度的纹理映射是活动的，则绑定的纹理被使用。实际上，纹理目标成为当前被绑定纹理的别名，并且纹理名称0指的是在初始化时被绑定的默认纹理。
	通过glBindTexture绑定的纹理仍旧是活动的直到同一个目标被其他纹理绑定或者该绑定纹理通过glDeleteTextures删除为止。
	一旦创建，一个已命名的纹理可能经常需要与维度匹配的目标多次绑定。这样利用glBindTexture来将一个已命名的纹理与一个纹理目标绑定，比利用glTexImage2D进行纹理图像的重载要快的多。
* 
*/
public class BasicGLRenderer implements Renderer {
	

	private float mRed;

	private float mGreen;

	private float mBlue;
	
	ColorSquare square = new ColorSquare();
	Square normalSquare = new Square();
	
	private final Group root = new Group();
	
	private Sixcorn sixcorn = new Sixcorn();
	
	SixcornTexture sixcornt = new SixcornTexture();
	float angle;
	
	/**
	 * 
	 * 在开始渲染的时候被调用，无论什么时候OpenGL ES 渲染不得不重新被创建。
	 * (渲染是典型的丢失并重新创建当活动被暂停或恢复。)
	 * 该方法一个创建长生命周期OpenGL资源(如材质)的好地方。
	 * 
	 */
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// Set the background color to black ( rgba ).
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);  // OpenGL docs.
		// Enable Smooth Shading, default not really needed.
		//启用smooth shading（阴影平滑）。阴影平滑通过多边形精细的混合色彩，并对外部光进行平滑，
		gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs.
		
		/**
		 * 这三行是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。
		 * 深度缓存不断的对物体进入屏幕内部有多深进行跟踪。
		 * 几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。它的排序决定那个物体先画。
		 * 这样您就不会将一个圆形后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。
		 */
		// Depth buffer setup.
		gl.glClearDepthf(1.0f);// OpenGL docs.
		// Enables depth testing.
		gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs.
		// The type of depth testing to do.
		gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs.
		
		//告诉OpenGL我们希望进行最好的透视修正
		// Really nice perspective calculations.
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.
                          GL10.GL_NICEST);
		
		//初始化
		// 创建一个新的plane
		SimplePlane plane = new SimplePlane(1, 1);

		// Move and rotate the plane.
		//z轴移动1.7
		plane.z = 1.7f;
		//x轴反向旋转65度
		plane.rx = -65;
		

		// 加载图片用作纹理
		plane.loadBitmap(ImageTool.getBitMap("jay.png"));
		
		root.add(plane);
		
		sixcornt.loadTexture(gl);
		//盒子
//		SimpleCube cube = new SimpleCube(1, 1, 1);
//		cube.z=1.7f;
//		cube.rx=-65;
//		root.add(cube);
		
	}

	
	/**
	 * 该方法在surface大小改变时被调用。这是设置你opengl视图端的好地方。
	 * 如果相机是固定的，不会围着场景移动，你也可以在这里设置你的相机。
	 * 
	 * 如果设备支持屏幕横向和纵向切换，这个方法将发生在横向<->纵向互换时。此时可以重新设置绘制的纵横比率
	 */
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		
		// 设置输出屏幕大小
		// Sets the current view port to the new size.
		gl.glViewport(0, 0, width, height);// OpenGL docs.
		// Select the projection matrix
		gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.
		// Reset the projection matrix
		gl.glLoadIdentity();// OpenGL docs.
		// Calculate the aspect ratio of the window
		GLU.gluPerspective(gl, 45.0f,
                                   (float) width / (float) height,
                                   0.1f, 100.0f);
		// Select the modelview matrix
		gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs.
		// Reset the modelview matrix
		gl.glLoadIdentity();// OpenGL docs.
	}

	
	/**
	 * 每帧的时候该方法都会被调用，这个用于画场景是可靠的。
	 * 你完全可以通过调用glClear方法开清楚帧缓存，接着通过其他的opengl ES来调用画当前的场景。
	 */
	@Override
	public void onDrawFrame(GL10 gl) {
		
		//设置清除颜色
		gl.glClearColor(mRed, mGreen, mBlue, 1.0f);

		// 用清除颜色清除  清除屏幕和深度缓存。
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		//重置观察矩阵
		gl.glLoadIdentity();
		
		gl.glTranslatef(0, 0, -4); 
		
		
		root.draw(gl);
		
//		sixcorn.draw(gl);
		
		// 重置矩阵
		gl.glLoadIdentity();
		// Z轴负方向移动10个单位
		gl.glTranslatef(0, 0, -10); 
		
		// SQUARE A
		// 保存当前矩阵
		gl.glPushMatrix();
		// Z轴正向旋转
		gl.glRotatef(angle, 0, 0, 1);
		// 绘制正方形
		gl.glColor4f(1,0, 0, 1);
		normalSquare.draw(gl);
		// 恢复矩阵
		gl.glPopMatrix();

		// SQUARE B
		// 保存矩阵
		gl.glPushMatrix();
		// z轴返向旋转
		gl.glRotatef(-angle, 0, 0, 1);
		// x轴移动2个单位
		gl.glTranslatef(2, 0, 0);
		// 缩小为原来的一半
		gl.glScalef(.5f, .5f, .5f);
		// 绘制正方形
		gl.glColor4f(0,1, 0, 1);
		normalSquare.draw(gl);			

		// SQUARE C
		// 在之前修改后没有恢复的前提下,保存当前矩阵
		gl.glPushMatrix();
		// z轴反向旋转
		gl.glRotatef(-angle, 0, 0, 1);
		//x轴移动两个单位
		gl.glTranslatef(2, 0, 0);
		// 缩小为一半
		gl.glScalef(.5f, .5f, .5f);
		// z轴反向旋转
		gl.glRotatef(angle*10, 0, 0, 1);
		// 绘制矩形
		gl.glColor4f(0,0, 1, 1);
		normalSquare.draw(gl);

		//恢复c
		gl.glPopMatrix();
		// 恢复B
		gl.glPopMatrix();

		// 角度递增
		angle++;
		
		
	}
	
	/**
	 * 添加一个网格
	 * @param mesh
	 */
	public void addMesh(Mesh mesh) {
		root.add(mesh);
	}
	
	public void setColor(float r, float g, float b) {
		mRed = r;
		mGreen = g;
		mBlue = b;
	}

}

